﻿using System;
using System.Diagnostics;
using System.Security.Permissions;

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.WebHost;
using TechTalk.SpecFlow;
using CodeStream.Testing.WebAutomation.InternetExplorer;

namespace CodeStream.Testing.WebAutomation.SpecFlow
{
    [Binding]
    [HostProtection(SecurityAction.LinkDemand, SharedState = true, Synchronization = true, ExternalProcessMgmt = true, SelfAffectingProcessMgmt = true)]
    [PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")]
    [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
    public class BrowserSpecFlowTools
    {
        public static TestContext TestContext { get; set; }
        public static Uri ServerUri { get; private set; }
    
        [BeforeFeature("webserver")]
        public static void BeforeFeature_WebServer()
        {
            Server server = new Server(15000, "/", TestContext.DeploymentDirectory);
            server.Start();
            ServerUri = new Uri(server.RootUrl);
            FeatureContext.Current.Add("webserver", server);
        }

        [AfterFeature("webserver")]
        public static void AfterFeature_WebServer()
        {
            Server server = null;
            if (FeatureContext.Current.TryGetValue<Server>("webserver", out server))
                server.Stop();
        }

        public static T GetUIMap<T>(string name, Func<Process, T> createDelegate) where T : class
        {
            T result = null;
            if (!ScenarioContext.Current.TryGetValue<T>(name, out result))
            {
                InternetExplorerInstance browser = null;
                if (!FeatureContext.Current.TryGetValue<InternetExplorerInstance>("Browser", out browser) || browser == null)
                    throw new InvalidOperationException("This scenario requires the @browser tag to be applied to initialize a browser instance.");
                result = createDelegate(browser.Browser);
                ScenarioContext.Current.Add(name, result);
            }

            return result;
        }

      }
}
